package top.xzxsrq.web.download;

import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

public abstract class DownloadManager {
    public static int THREAD_NUMBER = 3; // 一次执行的任务
    public static final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
            THREAD_NUMBER,
            THREAD_NUMBER,
            0L,
            TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<>(Integer.MAX_VALUE) // 存放一个超大的队列，避免新加的任务被抛弃
    );
    public static final List<DownloadThread> downloadList = new LinkedList<>();
    private static final List<Consumer<DownloadThread>> finishedCall = new LinkedList<>();
    public static synchronized Consumer<DownloadThread> addFinishedCall(Consumer<DownloadThread> add) {
        DownloadManager.finishedCall.add(add);
        return add;
    }
    public synchronized static Future<Void> submit(DownloadThread downloadThread) {
        downloadThread.addFinishedCall((unused)->{
            for (Consumer<DownloadThread> voidConsumer : DownloadManager.finishedCall) {
                voidConsumer.accept(downloadThread);
            }
        });
        Future<Void> submit = threadPoolExecutor.submit(downloadThread);
        downloadThread.setVoidFuture(submit);
        downloadList.add(downloadThread);
        return submit;
    }

    public synchronized static void cancel(String downloadId) {
        List<DownloadThread> removes=new LinkedList<>();
        for (DownloadThread downloadThread : downloadList) {
            if(downloadThread.getDownloadId().equals(downloadId)) {
                downloadThread.cancel();
                removes.add(downloadThread);
            }
        }
        downloadList.removeAll(removes);
    }

    public synchronized static void removeByThreadId(String threadId) {
        List<DownloadThread> removes=new LinkedList<>();
        for (DownloadThread downloadThread : downloadList) {
            if(downloadThread.getDownloadSelfId().equals(threadId)) {
                downloadThread.cancel();
                removes.add(downloadThread);
            }
        }
        downloadList.removeAll(removes);
    }

    public synchronized static boolean remove(DownloadThread thread) {
        return downloadList.remove(thread);
    }
}
